//
//  MBProgressHUD+Extension.swift
//  FrameProduct
//
//  Created by delegate on 2024/2/3.
//


//  提示框请使用Toast.swift中的api，本分类是内部类 配合Toast.swift实现的一部分
import MBProgressHUD

private let ToastDefaultDuration: TimeInterval = 3.0
private let MinSize = ScreenSize.minSize * 0.22

private struct MBProgressHUDKeys {
    static var actionBlock = "com.alpface.MBProgressHUD.actionBlock"
}

internal extension UIButton {
    
   fileprivate func tapWithActionBlock(_ block: (() -> Void)?) {
        self.actionBlock = block
        self.addTarget(self, action: #selector(tapAction), for: .touchUpInside)
    }
    
    private var actionBlock: (() -> Void)? {
        set {
            objc_setAssociatedObject(self, &MBProgressHUDKeys.actionBlock, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, &MBProgressHUDKeys.actionBlock)  as? () -> Void
        }
    }
    @objc private func tapAction() {
        if let block = actionBlock {
            block()
        }
    }
}


internal class MyProgressHUD: MBProgressHUD {
    
    var position: Toast.Position = .center {
        didSet {
            if oldValue == position {
                return
            }
            setNeedsUpdateConstraints()
        }
    }
    
    var onRemovedClosure: (() -> Void)?
    
    /// 是否在显示后自动隐藏，比如显示文本提示框，一般会在在显示3秒后自动隐藏，再比如有确定按钮的，则会在点击确定后才会被隐藏
    /// 默认值为true
    var isHideAfterDisplay: Bool = true
    private(set) var style: Toast.Style = .info
    
    static func createWithStyle(_ style: Toast.Style, title: String? = nil, message: String?) -> MyProgressHUD {
        var icon: UIImage?
        var hud: MyProgressHUD
        switch style {
        case .error:
            icon = UIImage(named: "icon_toast_error", in: Bundle.zzFoundation(), compatibleWith: nil)
            hud = MyProgressHUD.createTextHUD(title: title, message: message ?? "", icon: icon)
        case .activity:
            hud = MyProgressHUD.createActivityHUD(message: message)
            hud.isHideAfterDisplay = false
        case .info:
            icon = nil
            hud = MyProgressHUD.createTextHUD(title: title, message: message ?? "", icon: icon)
        case .imageInfo(let image, let message):
//            icon = UIImage(named: "icon_toast_success", in: Bundle.zzFoundation(), compatibleWith: nil)
//            hud = MyProgressHUD.createTextHUD(title: title, message: message ?? "", icon: icon)
            
            hud = MyProgressHUD.init()
            // 修改样式，否则等待框背景色将为半透明
            hud.bezelView.style = .solidColor
            // 设置等待框背景色为黑色
            hud.bezelView.backgroundColor = UIColor.black.withAlphaComponent(0.7)
            hud.removeFromSuperViewOnHide = true
            hud.detailsLabel.font = UIFont.lxs.font(name: .pingFangSCSemibold, size: 16)
            hud.detailsLabel.numberOfLines = 3
            hud.detailsLabel.text = message
            hud.mode = .customView
            hud.margin = 19
            hud.animationType = .zoom
            hud.detailsLabel.widthAnchor.constraint(lessThanOrEqualToConstant: ScreenSize.width * 0.5).isActive = true
            hud.detailsLabel.heightAnchor.constraint(equalToConstant: 48).isActive = true

            // 正方形 宽高是否相同
//            hud.isSquare = true
            // 设置内部控件的颜色，包括button的文本颜色，边框颜色，label的文本颜色等
            hud.contentColor = .white
            let btn = UIButton()
            btn.setImage(image, for: .normal)
            btn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 11, right: 0)
            btn.isUserInteractionEnabled = false
            hud.customView = btn
            btn.setContentHuggingPriority(.required, for: .horizontal)
            btn.setContentCompressionResistancePriority(.required, for: .horizontal)
    //        hud.customView = UIImageView(image: UIImage(named: "daily_signin_success"))
            
            hud.offset = CGPoint(x: 0, y: 35)
       
        case .warning:
            icon = UIImage(named: "icon_toast_success", in: Bundle.zzFoundation(), compatibleWith: nil)
            hud = MyProgressHUD.createTextHUD(title: title, message: message ?? "", icon: icon)
        case .custom(let view):
            hud = MyProgressHUD.createHUD(withCustomView: view)
            hud.isHideAfterDisplay = false
            hud.isUserInteractionEnabled = true
            hud.margin = 0
            hud.isSquare = false
            hud.bezelView.backgroundColor = .clear
            view.closeToast { [unowned hud] in
                hud.hide(animated: true)
            }
        }
        hud.style = style
        return hud
    }
    
    /// 让`CustomView`范围可以穿透ProgressHUD，允许其交互
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        guard self.mode == .customView, self.customView is ToastCustomable else {
            return super.hitTest(point, with: event)
        }
        if self.bezelView.frame.contains(point) {
            let convertPoint = self.convert(point, to: self.bezelView)
            let touchView = self.bezelView.hitTest(convertPoint, with: event)
            return touchView
//            if touchView is UIControl {
//                return view
//            }
        }
        return nil
    }
    
    override func updateConstraints() {
        super.updateConstraints()
        
        func removeCenterY() {
            let centerY = self.constraints.first {
                guard let first = $0.firstItem as? UIView,
                      let second = $0.secondItem as? UIView else {
                    return false
                }
                if first == self.bezelView, second == self,
                   $0.firstAttribute == .centerY,
                   $0.secondAttribute == .centerY {
                    return true
                }
                return false
            }
    
            if let centerY = centerY {
                removeConstraint(centerY)
            }
        }
        
        /// 根据`position` 添加约束
        var positionConstraint: NSLayoutConstraint?
        self.offset = offset
        switch position {
        case .top:
            removeCenterY()
            positionConstraint = NSLayoutConstraint(item: bezelView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: offset.y)
        case .bottom:
            removeCenterY()
            positionConstraint = NSLayoutConstraint(item: bezelView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: offset.y)
        case .center:
            // center 使用MBProgressHUD 自带的centerY 布局
            break
        }
        if let positionConstraint = positionConstraint {
            positionConstraint.priority = UILayoutPriority(999)
            positionConstraint.isActive = true
        }
    }
    
    internal static func huds(for view: UIView) -> [MyProgressHUD]? {
        return view.subviews.filter { view in
            if let hud = view as? MyProgressHUD {
                return hud.alpha > 0 && hud.superview != nil && hud.isHidden != true
            }
            return false
        } as? [MyProgressHUD]
    }
    
    override func removeFromSuperview() {
        super.removeFromSuperview()
        onRemovedClosure?()
        onRemovedClosure = nil
    }
}


internal extension MyProgressHUD {
    
    @discardableResult
    func setAction(_ action: Toast.Action) -> Self {
        self.isUserInteractionEnabled = true
        self.button.setTitle(action.title, for: .normal)
        self.button.setTitleColor(UIColor.white, for: .normal)
        self.button.contentEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 0, right: 10)
        self.button.titleLabel?.font = UIFont.lxs.font(name: .pingFangSCSemibold, size: 15)
        let lineTag = 111
        let line = self.bezelView.viewWithTag(lineTag) ?? UIView()
        line.tag = 111
        line.backgroundColor = .white
        self.bezelView.addSubview(line)
        line.translatesAutoresizingMaskIntoConstraints = false
        line.leadingAnchor.constraint(equalTo: self.bezelView.leadingAnchor).isActive = true
        line.trailingAnchor.constraint(equalTo: self.bezelView.trailingAnchor).isActive = true
        line.heightAnchor.constraint(equalToConstant: 1).isActive = true
        line.topAnchor.constraint(equalTo: self.button.topAnchor, constant: 0).isActive = true
        self.button.tapWithActionBlock { [weak self] in
            self?.hide(animated: true)
        }
        return self.self
    }
    
    // MARK: - Text
    @discardableResult
    static func createTextHUD(title: String? = nil, message: String, icon: UIImage? = nil) -> Self {
        let hud = self.createHud()
        hud.detailsLabel.text = message
        hud.label.text = title
        
        hud.mode = .customView
        
        if let icon = icon {
            hud.customView = UIImageView(image: icon)
            hud.minSize = CGSize(width: MinSize, height: MinSize)
        }
        return hud
    }
    
    // MARK: - Custom
    @discardableResult
    static func createHUD(withCustomView customView: UIView) -> Self {
        let hud = self.createHud()
        hud.mode = .customView
        hud.customView = customView
        return hud
    }
    
    // MARK: - Activity
    @discardableResult
    static func createActivityHUD(title: String? = nil, message: String?) -> Self {
        let hud = self.createHud()
        hud.mode = .indeterminate
        hud.detailsLabel.text = message
        hud.label.text = title
        hud.isUserInteractionEnabled = true
        hud.isSquare = true
        return hud
    }
    
    // MARK: - Init
    private static func createHud() -> Self {
        let hud = Self.init()
        // 修改样式，否则等待框背景色将为半透明
        hud.bezelView.style = .solidColor
        // 设置等待框背景色为黑色
        hud.bezelView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
        hud.removeFromSuperViewOnHide = true
        // 设置菊花框为白色
        UIActivityIndicatorView.appearance(whenContainedInInstancesOf: [MBProgressHUD.self]).color = UIColor.white
        hud.detailsLabel.font = UIFont.systemFont(ofSize: 15.0)
        hud.detailsLabel.numberOfLines = 0
        hud.label.numberOfLines = 1
        hud.label.font = UIFont.systemFont(ofSize: 16)
        hud.margin = 11.0
        hud.animationType = .zoom
        // 正方形 宽高是否相同
        hud.isSquare = false
        // 设置内部控件的颜色，包括button的文本颜色，边框颜色，label的文本颜色等
        hud.contentColor = .white
        return hud
    }
}
